using System;

namespace OhioState.Graphics
{
    /// <summary>
    /// List of supported Image formats
    /// </summary>
    public enum ImageFormat 
    { 
       /// <summary>
       /// RGBA format
       /// </summary>
        RGBA,
       /// <summary>
       /// RGB format
       /// </summary>
        RGB,
       /// <summary>
       /// ALPHA only
       /// </summary>
        ALPHA,
        /// <summary>
        /// LUMINANCE only
        /// </summary>
       LUMINANCE,
        /// <summary>
        /// RGBA16 format
        /// </summary>
       RGBA16 };
    
    /// <summary>
    /// Enumeration of different formats for storage
    /// </summary>
    public enum ByteFormat 
    {
        /// <summary>
        /// BYTE format
        /// </summary>
        BYTE,
        /// <summary>
        /// Short format
        /// </summary>
        SHORT, 
        /// <summary>
        /// Integer format
        /// </summary>
        INT, 
        /// <summary>
        /// Float format
        /// </summary>
        FLOAT, 
        /// <summary>
        /// Unsigned short format
        /// </summary>
        UNSIGNED_SHORT 
    };


    /// <summary>
    ///  Texel Format structure that holds the image format and the storage types
    /// </summary>
    [Serializable()]
    public struct TexelFormat
    {
        private ByteFormat _type;
        /// <summary>
        /// Get/Set Acessors for the texture type
        /// </summary>
        public ByteFormat Type
        {
            get { return _type; }
            set { _type = value; }
        }
        private ImageFormat _format;
        /// <summary>
        /// Get/Set Accessors for Image format
        /// </summary>
        public ImageFormat Format
        {
            get { return _format; }
            set { _format = value; }
        }
        /// <summary>
        /// Get Accessor that returns the size according to the byte format
        /// </summary>
        public int FormatSize
        {
            get
            {
                switch (_type)
                {
                    case ByteFormat.BYTE:
                        return NumChannels;
                    case ByteFormat.FLOAT:
                        return NumChannels * 4;
                    case ByteFormat.INT:
                        return NumChannels * 4;
                    case ByteFormat.SHORT:
                        return NumChannels * 2;
                    case ByteFormat.UNSIGNED_SHORT:
                        return NumChannels * 2;
                    default:
                        throw new ApplicationException("Serious Internal Error. ByteFormat is not recognized!");
                }
            }
        }

        /// <summary>
        /// Get Accessor that returns the number of channels based on the image format
        /// </summary>
        public int NumChannels
        {
            get
            {
                switch (_format)
                {
                    case ImageFormat.RGB:
                        return 3;
                    case ImageFormat.RGBA:
                        return 4;
                    case ImageFormat.ALPHA:
                        return 1;
                    case ImageFormat.LUMINANCE:
                        return 1;
                    case ImageFormat.RGBA16:
                        return 4;
                    default:
                        return 0;
                }
            }
        }
    }
    /// <summary>
    /// Interface for Textures
    /// </summary>
    public interface ITexture
    {
        /// <summary>
        /// Get Width
        /// </summary>
        int Width { get; }
        /// <summary>
        /// Get Height
        /// </summary>
        int Height { get; }
        /// <summary>
        /// Get Depth
        /// </summary>
        int Depth { get; }
        /// <summary>
        /// Get texture format
        /// </summary>
        TexelFormat TexelType { get; }
        /// <summary>
        /// bind texture method
        /// </summary>
        void bind();
        /// <summary>
        /// unbind texture method
        /// </summary>
        void unbind();
    }
}
